﻿using System;
using System.Collections.Generic;

namespace RouteMaster
{
    public class RouteItinerary : List<RouteLeg>
    {
        public int GetWeight()
        {
            TimeSpan tsTotal = GetTravelTime();

            // a change involves a penalty of 20 minutes.

            int weight = Count * 20;

            weight += (int)tsTotal.TotalMinutes;
            return weight;
        }

        public int GetWeightTo(BusStop bsTo)
        {
            TimeSpan tsTotal = GetTravelTimeTo(bsTo);

            // a change involves a penalty of 20 minutes.

            int weight = Count * 20;

            weight += (int)tsTotal.TotalMinutes;
            return weight;
        }

        public TimeSpan GetTravelTimeTo(BusStop bsTo)
        {
            var tsTotal = new TimeSpan();

            var temp = new List<RouteLeg>(this);
            temp.Reverse();

            var arr = temp.ToArray();

            for (int x = 0; x < arr.Length; x++)
            {
                if (arr[x]._busRoute == null)
                    break;
                if (x + 1 == arr.Length)
                {
                    var ts1 = arr[x]._busRoute.GetJourneyTime(arr[x]._busStopStart.ID, bsTo.ID);
                    tsTotal += ts1;
                    break;
                }
                var ts = arr[x]._busRoute.GetJourneyTime(arr[x]._busStopStart.ID, arr[x + 1]._busStopStart.ID);
                tsTotal += ts;
            }
            return tsTotal;
        }

        public TimeSpan GetTravelTime()
        {
            var tsTotal = new TimeSpan();

            var temp = new List<RouteLeg>(this);
            temp.Reverse();

            var arr = temp.ToArray();

            for (int x = 0; x < arr.Length; x++)
            {
                if (arr[x]._busRoute == null)
                    break;
                if (x + 1 == arr.Length)
                    break;

                var ts = arr[x]._busRoute.GetJourneyTime(arr[x]._busStopStart.ID, arr[x + 1]._busStopStart.ID);
                tsTotal += ts;
            }
            return tsTotal;
        }

        public Dictionary<string, string> ReportToDictionary()
        {
            var ret = new Dictionary<string, string>();

            var temp = new List<RouteLeg>(this);
            temp.Reverse();

            int i = 0;

            if (Count != 0)
            {
                int jouneyCount = Count - 1;
                ret.Add("" + i++, "This route has " + jouneyCount + " " + ((jouneyCount == 1) ? "journey" : "journeys") + ".");
                ret.Add("" + i++, "Travelling time: " + TimeSpanString.Stringify(TravellingTime())+ ".");
                ret.Add("" + i++, "");
            }
     
            for (int x = 0; x < temp.Count; x++)
            {
                if (temp[x]._busRoute == null)
                {
                    ret.Add("" + i++, "Arrive at " + temp[x]._busStopStart.PlaceName + ".");
                }
                else
                {
                    
                    ret.Add("" + i++, "At " + temp[x]._busStopStart.PlaceName + ",");
                    ret.Add("" + i++, "board the " + temp[x]._busRoute + " " + temp[x]._busRoute.VehicleType + ",");
                    ret.Add("" + i++, "journey duration " +
                        TimeSpanString.Stringify(temp[x]._busRoute.GetJourneyTime(temp[x]._busStopStart.ID, temp[x + 1]._busStopStart.ID))
                        + ".");
                 
                    ret.Add("" + i++, "");
                }
            }

            if (Count == 0)
            {
                ret.Add("1", "No route found!");
            }
            return ret;
        }

        // travelling time

        public TimeSpan TravellingTime()
        {
            var ts = new TimeSpan();

            var temp = new List<RouteLeg>(this);
            temp.Reverse();
       
            for (int x = 0; x < temp.Count; x++)
            {
                if (temp[x]._busRoute != null)
                {
                    ts += temp[x]._busRoute.GetJourneyTime(temp[x]._busStopStart.ID, temp[x + 1]._busStopStart.ID);
                }
            }
            return ts;
        }
    }
}
